package br.com.bmb.monitorimoveis.parser;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math3.util.Precision;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import br.com.bmb.monitorimoveis.entidade.Anuncio;
import br.com.bmb.monitorimoveis.entidade.InfoColeta;
import br.com.bmb.monitorimoveis.util.Convert;

public class WImoveisParser {	
	
	private static String urlBase = "http://www.wimoveis.com.br";

	/**
	 * Realiza o parse de um Document, originado de uma pagina web,
	 * extraindo dela as informações de um Anuncio.
	 * @param paginaAnuncio
	 * @return
	 * @throws Exception
	 */
	public static Anuncio parse(Document paginaAnuncio) throws Exception {
		Anuncio anuncio = new Anuncio();

		String tipoAnuncioAsStr = paginaAnuncio.select("#literalIdentificacao")
				.first().text().toUpperCase();

		if (tipoAnuncioAsStr.contains("VENDA")) {
			anuncio.setTipoAnuncio("VENDA");
		} else if (tipoAnuncioAsStr.contains("ALUGUEL")) {
			anuncio.setTipoAnuncio("ALUGUEL");
		}

		Element divDadosPrincipais = paginaAnuncio.select(".dados_principais")
				.first();

		Elements selecao = divDadosPrincipais.select("h2");

		anuncio.setLocalizacao(selecao.first().text());

		selecao = divDadosPrincipais.select("p");

		parseDadosPrincipais(selecao.text(), anuncio);
		
		selecao = paginaAnuncio.select(".dado_adicional");
		
		parseDadosAdicionais(selecao.first().text(), anuncio);
		
		return anuncio;
	}
	

	/**
	 * Obtem os dados de coleta do anuncio a partir de um elemento HTML.
	 * É usado para interpretar cada resultado de pesquisa e guarda-lo para 
	 * consultar a página do anuncio posteriormente.
	 * @param tagAnuncio
	 * @return
	 * @throws Exception
	 */
	public static InfoColeta obterURLColetaAnuncio(Element tagAnuncio) throws Exception {
		InfoColeta infoColeta = new InfoColeta();
		
		Element e = tagAnuncio.select("a").first();
		
		String url = e.attr("href");
		infoColeta.setUrl(urlBase + url);		
		
		int codigo = extrairCodigoDaURL(url);
		infoColeta.setCodAnuncio(codigo);

		infoColeta.setColetado(false);
		
		return infoColeta;
	}
	

	private static void parseDadosPrincipais(String dados, Anuncio anuncio) {

		String valor = anuncio.getTipoAnuncio().equals("VENDA") ? "Valor do Imóvel R$:" : "Valor do Aluguel R$:";
		String[] arrayDelimitadores = new String[] {"código:", "Atualização:",
				"Localização: Cidade:", "Bairro:", "Tipo:", "Quartos:",
				"Suites:", "Garagens:", "Elev:", valor,
				"Ágio: R$", "Valor m² :", "Área Útil:", "Condomínio:",
				"Aceita Financiar:"};
		
		List<String> tokens = criarTokens(dados, arrayDelimitadores);
		
//		for (String token : tokens) {
//			System.out.println("Token: " + token);
//		}
		
		anuncio.setCodigo(Convert.strToInt(tokens.get(0)));
		anuncio.setDataAtualizacao(Convert.strToDate(tokens.get(1)));
		anuncio.setCidade(tokens.get(2));
		anuncio.setBairro(tokens.get(3));
		anuncio.setTipoImovel(tokens.get(4));
		anuncio.setQuartos(Convert.strToInt(tokens.get(5)));
		anuncio.setSuites(Convert.strToInt(tokens.get(6)));
		anuncio.setVagas(Convert.strToInt(tokens.get(7)));
		anuncio.setElevadores(Convert.strToInt(tokens.get(8)));
		anuncio.setPreco(Convert.strToDoubleWithFormat(tokens.get(9)));
		anuncio.setPrecoAgio(Convert.strToDoubleWithFormat(tokens.get(10)));
		anuncio.setPrecoM2(Convert.strToDoubleWithFormat(tokens.get(11)));
		anuncio.setAreaUtil(Convert.strToDoubleWithFormat(tokens.get(12)));
		anuncio.setPrecoCondominio(Convert.strToDoubleWithFormat(tokens.get(13)));
		anuncio.setAceitaFinanciamento(Convert.strToBool(tokens.get(14)));

	}

	private static void parseDadosAdicionais(String dados, Anuncio anuncio) {

		String[] arrayDelimitadores = new String[] {"Adicionais do Imóvel Imóvel Pronto:", "Área do Terreno:",
				"Área Total:", "Andar:", "Andares:", "Posição:",
				"Posição do sol:"};
		
		List<String> tokens = criarTokens(dados, arrayDelimitadores);
		

//		for (String token : tokens) {
//			System.out.println("Token: " + token);
//		}
		
		
		anuncio.setPronto(tokens.get(0).equals("SIM") ? true : false);
		anuncio.setAreaTerreno(Convert.strToDouble(tokens.get(1)));
		anuncio.setAreaTotal(Convert.strToDoubleWithFormat(tokens.get(2)));
		anuncio.setAndar(Convert.strToInt(tokens.get(3)));
		anuncio.setAndares(Convert.strToInt(tokens.get(4)));
//		anuncio.setPosicao(tokens.get(5));
//		
//		String delimitador = "Posição do sol: ";
//		String str = dados.substring(dados.indexOf(delimitador) + delimitador.length());
//		
//		str = str.substring(0, str.indexOf(" "));
//		
//		anuncio.setPosicaoSol(str);
		
	}

	private static List<String> criarTokens(String dados,
			String[] arrayDelimitadores) {
		//System.out.println(dados);
		
		List<String> tokens = new ArrayList<String>();
		
		for (int i = 0; i < arrayDelimitadores.length; i++) {
			
			int indInicio, indFim  = 0;
			String token = "";
			
			indInicio = dados.indexOf(arrayDelimitadores[i]) + arrayDelimitadores[i].length();
			
			if (i == arrayDelimitadores.length - 1) {
				token = dados.substring(indInicio);
			} else {
				indFim = dados.indexOf(arrayDelimitadores[i+1]);
				token = dados.substring(indInicio, indFim);
			}
			
			tokens.add(token.replace("m²", "").replace(String.valueOf((char)160), "").replace(" ", ""));
		}
		return tokens;
	}

	
	/**
	 * No Wimoveis, o código do anúncio é exibido no final da URL.
	 * Esse método extrai o código do anuncio a partir da URL.
	 * @param url
	 * @return
	 */
	private static int extrairCodigoDaURL(String url) {
		
		String codAsStr = url.substring(url.lastIndexOf("-") + 1);
		
		return Integer.valueOf(codAsStr);
	}

	/**
	 * Faz o parse de cada anuncio contido na pagina de resultado de pesquisa.
	 * @param tagAnuncio
	 * @return
	 * @throws Exception
	 */
	public static Anuncio parse(Element tagAnuncio) throws Exception {

		Anuncio anuncio = new Anuncio();

		Elements elements = tagAnuncio.select(".localizacaoBairro a");

		int index = 0;
		if (elements.size() == 2) {
			index = 1;
		}

		Element e = elements.get(index);

		anuncio.setLocalizacao(e.text());

		Elements icones = tagAnuncio.select(".icones");

		anuncio.setQuartos(Convert.strToInt(icones.get(0).text()));
		anuncio.setSuites(Convert.strToInt(icones.get(1).text()));
		anuncio.setVagas(Convert.strToInt(icones.get(2).text()));

		String areaAsStr = tagAnuncio.select(".m2").first().text();
		areaAsStr = areaAsStr.substring(1);
		areaAsStr = areaAsStr.replace(",", ".");

		anuncio.setAreaUtil(Convert.strToDouble(areaAsStr));

		String valorAsStr = tagAnuncio.select(".valor a b").first().text();
		valorAsStr = valorAsStr.replace(".", "");
		valorAsStr = valorAsStr.replace(",", ".");

		anuncio.setPreco(Convert.strToDouble((valorAsStr)));

		// String valorM2AsStr =
		// tagAnuncio.select(".valor font").first().text();
		// valorM2AsStr = valorM2AsStr.replace("Valor m²: ", "").replace(".",
		// "").replace(",", ".");
		// anuncio.setValorM2(strToDouble(valorM2AsStr));

		double precoMetro = anuncio.getPreco() / anuncio.getAreaUtil();
		anuncio.setPrecoM2(Precision.round(precoMetro, 2));
		return anuncio;
	}
	
}
